package com.globallogic.university;

import java.util.Iterator;

/**
 *  The class implements a schedule of learning .
 */
public class Calendar {

    public static final int daysOfWeek = 5;
    public static final int countLessonsOfDay = 5;

	private Lesson[][] lessons;

	public Lesson[][] getLessons() {
		return this.lessons;
	}

    /** Setting subject in schedule.
     * @param group -- link to object of Students group class.
     * @param subject -- link to object of Subject class.
     * @param day -- current number day of week (0..daysOfWeek-1).
     * @param iLesson -- current number of lesson in current day (0..countLessonsOfDay-1).
     */
    private void setLesson(StudentsGroup group, Subject subject, int day, int iLesson) {
        lessons[day][iLesson] = new Lesson(subject,subject.getTeacher(),group);
        subject.setTimes_a_week(subject.getTimes_a_week() - 1);
        subject.getTeacher().addLesson(day, iLesson, lessons[day][iLesson]);
        if (subject.getTimes_a_week() == 0) {  // если количество занятий исчерпано, удаляем из списка, чтоб не мешал.
            group.getSubjects().remove(subject);
        }
    }

    /**
     * Create schedule of learning for group
     * @param group - link to object of Students group class.
     */
    public void calcLessons4Group(StudentsGroup group) {
        lessons = new Lesson[daysOfWeek][countLessonsOfDay];
        Subject subject;

        for (int iLesson = 0; iLesson < countLessonsOfDay; iLesson++) {
            for (int day = 0; day < daysOfWeek; day++) {
                subject = findSubject(group, day, iLesson); // выбираем предмет для рассписания.
                if (subject != null) {  // нашли.
                    setLesson(group, subject,day, iLesson);
                }

            }
        }
    }

    /**
     * Check can use current subject.
     * @param subject -- link to object of Subject class.
     * @param lessons -- link to object of current schedule array.
     * @param day -- current number day of week (0..daysOfWeek-1).
     * @param iLesson -- current number of lesson in current day (0..countLessonsOfDay-1).
     * @return -- if true then current subject can use.
     */
    private boolean isCanUse(Subject subject, Lesson[][] lessons, int day, int iLesson) {
        Teacher teacher = subject.getTeacher();
        boolean result = !teacher.isBusy(day,iLesson) && (subject.getTimes_a_week() > 0);

        if (result) {
            int idx = 0; // счетчик занятий
            if (iLesson > 0) {  //если это не первая пара, то проверяем есть ли уже такой предмет сегодня
                do {
                    result = !subject.equals(lessons[day][idx].getSubject());
                    idx++;
                } while (result && idx < iLesson);
            }

            if(result && (day > 0)) { //если все ОК и это не понедельник, то проверяем, была ли эта пара вчера.
                idx = 0;
                do {
                    result = !subject.equals(lessons[day - 1][idx].getSubject());
                    idx++;
                } while (result && idx <= iLesson);
            }
        }
        return result;
    }

    /**
     * Find subject to current day and current number of lesson of schedule.
     * @param group -- link to object of Students group class.
     * @param day -- current number day of week (0..daysOfWeek-1).
     * @param iLesson  -- current number of lesson in current day (0..countLessonsOfDay-1).
     * @return  -- link to object of Subject class.
     */
    private Subject findSubject(StudentsGroup group, int day, int iLesson) {
        Iterator<Subject> subjects = group.getSubjects().iterator();
        Subject subject = null;
        while (subjects.hasNext()) { //у нас есть доступные предметы.
            subject = subjects.next();
            if (isCanUse(subject, lessons, day, iLesson)) { //можем ли мы его использовать?
                return subject;
            }
        }
        if ((subject != null) && (subject.getTimes_a_week() > 0)) { //Если нельзя, но очень хочется, то можно.
            return subject;
        } else {
            return null; //предметы закончились
        }
    }
}